# InheritedElementIterator.java

    package org.codefilarete.tool.bean;

    import java.util.Collections;
    import java.util.Iterator;
    import java.util.NoSuchElementException;

    import org.codefilarete.tool.collection.ArrayIterator;
    import org.codefilarete.tool.collection.ReadOnlyIterator;

    /**
     * An {@link java.util.Iterator} that gets its information from each class of a hierarchy.
     *
     * @author Guillaume Mary
     */
    public abstract class InheritedElementIterator<T> extends ReadOnlyIterator<T> {

    	protected Iterator<Class<?>> classIterator;
    	protected Iterator<T> inheritedElementIterator = Collections.emptyIterator();

    	public InheritedElementIterator(Class<?> aClass) {
    		this(new ClassIterator(aClass));
    	}

    	public InheritedElementIterator(Iterator<Class<?>> classIterator) {
    		this.classIterator = classIterator;
    	}

    	@Override
    	public boolean hasNext() {
    		// simple case
    		if (inheritedElementIterator.hasNext()) {
    			return true;
    		} else {
    			// no more element for the current iterator => we must scan upper classes if they have some
    			while (classIterator.hasNext() && !inheritedElementIterator.hasNext()) {
    				// transforming the class elements to an Iterator
    				inheritedElementIterator = nextInheritedElementIterator(classIterator.next());
    			}
    			return inheritedElementIterator.hasNext();
    		}
    	}

    	protected Iterator<T> nextInheritedElementIterator(Class clazz) {
    		return new ArrayIterator<>(getElements(clazz));
    	}

    	@Override
    	public T next() {
    		if (!hasNext()) {
    			throw new NoSuchElementException();
    		}
    		return inheritedElementIterator.next();
    	}

    	/**
    	 * Gives any element from a class: field, method, interface, ...
    	 *
    	 * @param clazz the class for which elements must be given
    	 * @return an array of elements, not null
    	 */
    	protected abstract T[] getElements(Class<?> clazz);
    }